package cn.wolfcode.shop.redis;

import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import java.util.HashMap;
import java.util.Map;

public class RedisTemplate {

    @Autowired
    private JedisPool pool;

    public <T> boolean set(Keyprefix keyprefix, String key, T data){
        try (Jedis jedis = pool.getResource()){
            String realKey = keyprefix.getPrefix() + key;
            String dataVal = beanToString(data);
            if (keyprefix.getEXpireSeconds() > 0){
                // 设置了失效时间，需要使用setex方法
                jedis.setex(realKey, keyprefix.getEXpireSeconds(), dataVal);
            }else {
                // 没有设置失效时间，需要使用set方法
                jedis.set(realKey,dataVal);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    public <T> boolean hset(Keyprefix keyprefix, String key, String field,T data){
        try (Jedis jedis = pool.getResource()){
            String realKey = keyprefix.getPrefix() + key;
            String dataVal = beanToString(data);
            jedis.hset(realKey,field,dataVal);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    public <T> T get(Keyprefix keyprefix, String key, Class<T> clzz){
        try (Jedis jedis = pool.getResource()){
            String realKey = keyprefix.getPrefix() + key;
            String dataVal = jedis.get(realKey);
            return StringToBean(dataVal,clzz);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public <T> T hget(Keyprefix keyprefix, String key, String field,Class<T> clzz){
        try (Jedis jedis = pool.getResource()){
            String realKey = keyprefix.getPrefix() + key;
            String dataVal = jedis.hget(realKey,field);
            return StringToBean(dataVal,clzz);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public <T> Map<String,T> hgetAll(Keyprefix keyprefix, String key, Class<T> clzz){
        try (Jedis jedis = pool.getResource()){
            String realKey = keyprefix.getPrefix() + key;
            Map<String, String> map = jedis.hgetAll(realKey);
            HashMap<String , T> resultMap = new HashMap<>();
            for (Map.Entry<String,String> entry : map.entrySet()){
                resultMap.put(entry.getKey(),StringToBean(entry.getValue(),clzz));
            }
            return resultMap;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    // 判断key是否存在
    public Boolean exists(Keyprefix keyprefix, String key){
        try (Jedis jedis = pool.getResource()){
            String realKey = keyprefix.getPrefix() + key;
            return jedis.exists(realKey);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    // 设置失效时间
    public Long expire(Keyprefix keyprefix, String key, int expireSeconds){
        try (Jedis jedis = pool.getResource()){
            String realKey = keyprefix.getPrefix() + key;
            return jedis.expire(realKey, expireSeconds);
        } catch (Exception e) {
            e.printStackTrace();
            return -3L;
        }
    }

    // 数值递增
    public Long incr(Keyprefix keyprefix, String key){
        try (Jedis jedis = pool.getResource()){
            String realKey = keyprefix.getPrefix() + key;
            return jedis.incr(realKey);
        } catch (Exception e) {
            e.printStackTrace();
            return Long.MIN_VALUE;
        }
    }

    // 数值递减
    public Long decr(Keyprefix keyprefix, String key){
        try (Jedis jedis = pool.getResource()){
            String realKey = keyprefix.getPrefix() + key;
            return jedis.decr(realKey);
        } catch (Exception e) {
            e.printStackTrace();
            return Long.MAX_VALUE;
        }
    }

    private <T> T StringToBean(String dataVal, Class<T> clzz) {
        if (int.class == clzz || Integer.class == clzz){
            return (T) Integer.valueOf(dataVal);
        }else if(short.class == clzz || Short.class == clzz){
            return (T) Integer.valueOf(dataVal);

        }else if(long.class == clzz || Long.class == clzz){
            return (T) Integer.valueOf(dataVal);

        }else if(double.class == clzz || Double.class == clzz){
            return (T) Integer.valueOf(dataVal);

        }else if(boolean.class == clzz || Boolean.class == clzz){
            return (T) Integer.valueOf(dataVal);

        }else if(String.class == clzz){
            return (T) dataVal;

        }else {
            return JSON.parseObject(dataVal,clzz);
        }

    }

    private <T> String beanToString(T data) {
        Class<?> clzz = data.getClass();
        if (int.class == clzz || Integer.class == clzz){
            return data+"";
        }else if(short.class == clzz || Short.class == clzz){
            return data+"";

        }else if(long.class == clzz || Long.class == clzz){
            return data+"";

        }else if(double.class == clzz || Double.class == clzz){
            return data+"";

        }else if(boolean.class == clzz || Boolean.class == clzz){
            return data+"";

        }else if(String.class == clzz){
            return (String) data;

        }else {
            return JSON.toJSONString(data);
        }
    }

}
